/*
 * MorenoApp.java
 */
package morenoapp;

import java.io.IOException;
import morenoapp.action.MorenoActions;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.SplashScreen;
import java.io.File;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import morenoapp.components.workplace.WorkplaceView;
import morenoapp.logging.MorenoLog;
import morenoapp.model.MorenoModelException;
import morenoapp.model.app.MorenoApplicationData;
import morenoapp.model.app.MorenoApplicationData.ResourceDescriptor;
import morenoapp.model.data.MorenoModelFace;
import morenoapp.net.MorenoNet;
import morenoapp.resources.ResourcesHolder;
import morenoapp.util.I18N;
import morenoapp.util.MorenoUtil;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;

/**
 * The main class of the application.
 * @author dmitry.mamonov
 */
public class MorenoApp extends SingleFrameApplication {
    private static MorenoApp application = null;
    /**
     * Common application data.
     */
    private MorenoApplicationData applicationData = new MorenoApplicationData();

    @Override
    protected void initialize(String[] args) {
        System.out.println("initialize");
        super.initialize(args);

        //setup logging
        MorenoLog.configureLogging();

        //setup custom user interface options
        ToolTipManager.sharedInstance().setDismissDelay(30000);

        { //setup user language
            String selectedLocaleLanguage = MorenoApplicationData.getPrefferedLocale();
            if (selectedLocaleLanguage != null) {
                Locale locale = new Locale(selectedLocaleLanguage);
                Locale.setDefault(locale);
            }
        }

        //add UI (EDT) exception handler
        Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                MorenoNet.createIssue(e);
                MorenoLog.notifyUnknownException(e);
                final Thread.UncaughtExceptionHandler handler = this;
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        Thread.currentThread().setUncaughtExceptionHandler(handler);
                    }

                });
            }

        });

                //load recent document (only in debug mode)
        if (MorenoUtil.isDebug()) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    List<ResourceDescriptor> recent =
                            MorenoApp.getApplicationData().getRecentOpennedResouces();
                    if (recent.size() > 0) {
                        try {
                            MorenoApp.getModel().loadModel(new File(recent.get(0).getResource()));
                        } catch (MorenoModelException ex) {
                            MorenoLog.notifyUnknownException(ex);
                        }
                    }
                }
            });
        }
    }



    /**
     * At startup create and show the main frame of the application.
     */
    @Override
    protected void startup() {
        System.out.println("startup");

        //initialize actions object and setup model
        MorenoActions.getInstance().setupModel(getModel());

        //Устанавливаем главную панель
        this.show(new MorenoMainView(this));
    }

    @Override
    protected void ready() {
        System.out.println("ready");
        super.ready();

        //apply navigation state to actions
        MorenoActions.getInstance().setupWorkplaceNavigator(getMainView().getNavigator());

        //activate welcome view at first
        getMainView().getNavigator().activateView(WorkplaceView.WelcomeView);
    }

    @Override
    public MorenoMainView getMainView() {
        return (MorenoMainView) super.getMainView();
    }

    /**
     * This method is to initialize the specified window by injecting resources.
     * Windows shown in our application come fully initialized from the GUI
     * builder, so this additional configuration is not needed.
     * @param root 
     */
    @Override
    protected void configureWindow(java.awt.Window root) {
        System.out.println("configureWindow");
        //Устанавливаем иконку приложения
        //TODO change to accurate resource
        ImageIcon icon = new ImageIcon(ResourcesHolder.class.getResource("knewstuff-32.png")); //NOI18N
        root.setIconImage(icon.getImage());
    }

    @Override
    protected void shutdown() {
        //TODO stop some asynchronous process in exits
        super.shutdown();
    }

    /**
     * A convenient static getter for the application instance.
     * @return the instance of MorenoApp
     */
    public static MorenoApp getApplication() {
        if (application == null) {
            application = Application.getInstance(MorenoApp.class);
        }
        return application;

    }

    /**
     * A convenient static getter for the application data instance.
     * @return the instance of MorenoApp
     */
    public static MorenoApplicationData getApplicationData() {
        return getApplication().applicationData;
    }

    public static MorenoModelFace getModel() {
        return getApplicationData().
                getMorenoModelProxy();
    }

    public static void showSorryDialog(JComponent _component) {
        String messageLong = "<html>" + //NOI18N
                I18N.getString("label.function_is_not_yet_implemented", (_component.getToolTipText() != null ? "'" + _component.getToolTipText() + "' " : ""));
        int addedSymbolsCount = 0;
        String messageWrapped = "";
        for (String item : messageLong.split("\\s+")) { //NOI18N
            if (!messageWrapped.isEmpty()) {
                messageWrapped += " "; //NOI18N
            }
            messageWrapped += item;
            addedSymbolsCount += item.length();
            if (addedSymbolsCount > 60) {
                addedSymbolsCount = 0;
                messageWrapped += "<br/>\n"; //NOI18N
            }
        }

        JOptionPane.showMessageDialog(SwingUtilities.getRoot(_component),
                messageWrapped,
                I18N.get("label.functional_is_not_implemented"),
                JOptionPane.INFORMATION_MESSAGE);
    }

//    public static void showExceptionDialog(String message, Exception ex) {
//        JOptionPane.showMessageDialog(getApplication().getMainFrame(),
//                "<html><b>" + message + "</b><br><br><br>\n" +
//                "<p style=\"width: 400px\">" + ex.getMessage() + "</p>",
//                I18N.get("morena.exception_dialog_title"),
//                JOptionPane.ERROR_MESSAGE);
//    }

    private static void startStartupProgressRun() {
        new SwingWorker() {
            @Override
            protected Object doInBackground() throws Exception {
                final SplashScreen ss = SplashScreen.getSplashScreen();
                if (ss != null) {
                    Graphics g = ss.createGraphics();
                    int progress = 0;
                    while (ss.isVisible() == true) {
                        g.setColor(Color.ORANGE);
                        progress += 10;
                        g.fillRect(0, 270, progress, 3);
                        ss.update();
                        Thread.sleep(250);
                    }
                    this.done();
                } else {
                    System.out.println("none");
                }
                System.out.println("done");
                return "OK";
            }

        }.execute();
    }

    private static Properties versionInfo;
    private static Properties getVersionInfo(){
        if (versionInfo==null){
            versionInfo = new Properties();
            try {
                versionInfo.load(MorenoApp.class.getResourceAsStream("morena_version.properties"));
            } catch (IOException ex) {
                MorenoLog.warn(ex);
            }
        }
        return versionInfo;
    }

    /**
     * Provedes current version number of application.
     * @return
     */
    public static String getVersion(){
        return getVersionInfo().getProperty("morena.version","Unknown");
    }


    /**
     * Privides current build number of application.
     * @return
     */
    public static String getBuild(){
        return getVersionInfo().getProperty("morena.build","00000000");
    }

    /**
     * Main method launching the application.
     * @param args
     */
    public static void main(String[] args) {
        startStartupProgressRun();

        launch(MorenoApp.class, args);
    }

}
